package net.wanho.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * Author：汤小洋
 * Date：2024-01-26 9:17
 * Description：<描述>
 */
@Configuration
public class RabbitMqConfig {

    @Value("${shop.exchange}")
    private String exchange;

    @Value("${shop.queue}")
    private String queue;

    @Value("${shop.routingKey}")
    private String routingKey;

    @Bean
    public Exchange exchange(){
        // new FanoutExchange();
        // new TopicExchange();
        return new DirectExchange(exchange);
    }

    @Bean
    public Queue queue(){
        return new Queue(queue);
    }

    @Bean
    public Binding binding(Exchange exchange, Queue queue){
       return BindingBuilder.bind(queue).to(exchange).with(routingKey).noargs();
    }

    /**
     * 消息转换器
     */
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    /**
     * 初始化，绑定回调
     */
    @Resource
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init(){
        // 消息发送到交换机回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if(ack){
                // System.out.println("成功，消息已成功到达交换机！！");
            }else{
                // todo
                System.out.println("失败，消息未到达交换机！！");
            }
        });

        // 消息发送到队列回调
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            // todo
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("失败，消息未到达队列！！-----" + replyCode + "," + replyText);
        });
    }


    /**
     * 死信
     */
    @Bean
    public Exchange normalExchange(){
        return new DirectExchange("normal.exchange");
    }

    @Bean
    public Queue normalQueue(){
        Map<String, Object> arguments =new HashMap<>();
        arguments.put("x-max-length",1); // 设置队列中消息的最大数量
        arguments.put("x-message-ttl",2); // 设置队列中消息的过期时间，单位毫秒
        arguments.put("x-dead-letter-exchange","dead.exchange"); // 设置死信交换机
        arguments.put("x-dead-letter-routing-key","dead.key"); // 设置死信路由键

        return new Queue("normal.queue",true,false,false,arguments); // 队列名，是否持久化，是否排他，是否自动删除，其他参数
    }

    @Bean
    public Binding normalBinding(){
        return BindingBuilder.bind(normalQueue()).to(normalExchange()).with("normal.key").noargs();
    }

    @Bean
    public Exchange deadExchange(){
        return new DirectExchange("dead.exchange");
    }

    @Bean
    public Queue deadQueue(){
        return new Queue("dead.queue");
    }

    @Bean
    public Binding deadBinding(){
        return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("dead.key").noargs();
    }

}
